dbtのHookで複数クエリを記述する方法を確かめてみた #dbt
さがらです。
dbtではHookという機能を使うことで、modelの実行前後に指定したクエリを実行することが可能です。
Hookについての詳細は、すでに弊社で検証を一度行っておりますのでこちらを御覧ください。
このHookについて、「複数クエリを実行したい」というケースは多いと思うのですが、公式Docに記載されている例は1つのクエリだけでHookを使用するコードしか書かれていませんでした。
そのため、小ネタではありますが、本記事では「dbtのHookで複数クエリを記述する方法」をまとめてみたいと思います。
modelファイルに記述する方法
config
の中にpre_hook
等の設定を行うのですが、[]の中で、ダブルクォーテーションで実行したいクエリを囲み、各クエリの区切りはカンマを記述すればOKです。
{{ config( pre_hook=[ "use role sagara_admin_role", "use role sagara_select_role", "use role sagara_dev_role" ] ) }}
下図のように、[]内で記述した順番にクエリが実行されているのがわかると思います。
dbt_project.ymlに記述する方法
dbt_project.yml
ファイル内で、models
パラメータ内に+pre_hook:
と記述して、その下に実行したいクエリを順番に記述すればOKです。
modelsフォルダ内で子フォルダを作成している場合は、そのフォルダを指定することでHookの実行範囲を指定することも可能です、(下記のサンプルだと、marts
フォルダ内のmodelファイルに対してのみ、+pre_hook:
に記述したクエリが実行されます。)
models: jaffle_shop: staging: materialized: view marts: materialized: table +pre-hook: - "use role sagara_admin_role" - "use role sagara_select_role" - "use role sagara_dev_role"
実際に実行した後の履歴を見ると、一番下の2つのクエリはstaging
フォルダ内のmodelに該当するクエリのためpre_hookが適用されておらず、一番上のクエリはmarts
フォルダ内のmodelのため、+pre_hook:
に記述したクエリが実行されております。
おまけ:modelファイルにもdbt_project.ymlにもHookを記述した場合の挙動
自分が気になったので、modelファイルにもdbt_project.ymlにもHookを記述した場合の挙動を確認してみます。
marts
フォルダ内にあるmodelに対して、下記のようにmodelファイルにもdbt_project.yml
にも、pre_hook
を設定しておきます。
- modelファイル内
{{ config( pre_hook=[ "use role sagara_dev_role", "use role sagara_dev_role", "use role sagara_dev_role" ] ) }}
- dbt_project.yml内
models: jaffle_shop: staging: materialized: view marts: materialized: table +pre-hook: - "use role sagara_admin_role" - "use role sagara_admin_role" - "use role sagara_admin_role"
この上でdbt runを実行すると…dbt_project.yml内で記述したpre_hook実行後に、modelファイル内に記述したpre_hookが実行されました
他の設定だと、dbt_project.yml
で記述した設定がmodelファイル内の記述内容で上書きされることが多いと思いますが、Hookでは上書きされずにどちらも実行されるみたいですね!(実行順序はmodelファイルの内容が後になりますが)
まとめ
dbtのHookで複数クエリを記述する方法をまとめてみました。
特に、SQLでほぼ全ての操作を実行できるSnowflakeではHookの有用性が特に高いと思いますので、ぜひ活用してみてください!